package org.szy.anon.service.impl;

import cn.dev33.satoken.session.SaSession;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.StrUtil;
import org.noear.solon.Utils;
import org.noear.solon.annotation.Inject;
import org.noear.solon.annotation.ProxyComponent;
import org.noear.solon.core.event.EventBus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.szy.anon.pojo.LoginBodyParam;
import org.szy.anon.service.AnonService;
import org.szy.core.auth.util.SaUtil;
import org.szy.core.common.entity.LoginUser;
import org.szy.core.common.enums.CommonStatusEnum;
import org.szy.core.common.enums.UserTypeEnum;
import org.szy.core.common.exception.BaseException;
import org.szy.core.common.uilts.AvatarUtil;
import org.szy.plugin.dev.service.DevLoginLogService;
import org.szy.plugin.sys.entity.SysUser;
import org.szy.plugin.sys.service.SysPermissionService;
import org.szy.plugin.sys.service.SysUserService;

import java.util.*;

/**
 * 不拦截业务实现类
 *
 * @author 孙志阳
 * @date 2023-02-16
 * @since 1.0.0
 **/
@ProxyComponent
public class AnonServiceImpl implements AnonService {

    Logger log = LoggerFactory.getLogger(AnonServiceImpl.class);
    @Inject
    private SysUserService sysUserService;
    @Inject
    private SysPermissionService sysPermissionService;
    @Inject
    private DevLoginLogService devLoginLogService;

    @Override
    public Map<String, String> login(LoginBodyParam param) {
        String account = param.getAccount();
        String password = param.getPassword();
        if (StrUtil.isEmpty(account) || StrUtil.isEmpty(password)) {
            throw new BaseException("账号或密码未填写");
        }
        UserTypeEnum typeEnum = UserTypeEnum.SYS_USER;
        log.info("用户类型：【{}】用户名：【{}】，请求登录系统。", typeEnum.getValue(), account);
        //根据账号获取用户信息
        SysUser sysUser = sysUserService.getByAccount(account);
        if (sysUser == null) throw new BaseException("账号或密码不正确");
        //校验密码是否正确
        if (!SaUtil.verifyPwd(password, sysUser.getPassword())) {
            devLoginLogService.add(typeEnum.getValue(), sysUser.getId(), sysUser.getAccount(), 0, "登录失败，账号或密码不正确");
            throw new BaseException("账号或密码不正确");
        }
        //校验用户状态是否正确
        if (!Objects.equals(sysUser.getStatus(), CommonStatusEnum.ENABLE.getKey())) {
            devLoginLogService.add(typeEnum.getValue(), sysUser.getId(), sysUser.getAccount(), 0, "登录失败，账号已停用");
            throw new BaseException("对不起，您的账号已停用，请联系管理员");
        }
        StpUtil.login(sysUser.getId());
        SaSession session = StpUtil.getSession(true);
        devLoginLogService.add(typeEnum.getValue(), sysUser.getId(), sysUser.getAccount(), 1, "登录成功");

        //根据用户id获取角色列表
        Set<String> roleCodes = sysPermissionService.getRoles(sysUser.getId());
//        roleCodes.add("wangbuhao");
        //根据用户角色获取权限列表
        Set<String> permission = sysPermissionService.getPermissionsByRoleCode(StrUtil.join(",", roleCodes));
        //创建登录用户
        LoginUser loginUser = new LoginUser();
        loginUser.builderLoginUser(loginUser);
        loginUser.setUserId(sysUser.getId());
        loginUser.setUserName(sysUser.getAccount());
        loginUser.setName(sysUser.getName());
        loginUser.setUserType(typeEnum.getKey());
        //如果用户头像不为空，则更新头像
        if (StrUtil.isEmpty(sysUser.getAvatar())) {
            loginUser.setAvatar(AvatarUtil.pathImg(sysUser.getName()));
            sysUserService.modifyAvatar(sysUser.getId(), loginUser.getAvatar());
        } else {
            loginUser.setAvatar(sysUser.getAvatar());
        }
        loginUser.setRoles(new ArrayList<>(roleCodes));
        loginUser.setPermissions(new ArrayList<>(permission));

        //获取session
        session.set("loginUser", loginUser);
        session.set("loginId", StpUtil.getLoginIdAsString());

        loginUser.setExpireSecond(session.getTimeout());
        loginUser.setCreateTime(session.getCreateTime());

        /**
         * 发布登录用户
         */
        EventBus.pushAsync(loginUser);

        //构建map
        Map<String, String> map = new HashMap<>(2);
        map.put("name", loginUser.getName());
//        map.put(StpUtil.getTokenName(), StpUtil.getTokenValue());

        return map;
    }
}
